﻿using System;
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.ResourceManagement.AsyncOperations;
using UnityEngine.ResourceManagement.ResourceProviders;
using UnityEngine.SceneManagement;

namespace Pisces
{
	/**
	 * 资源管理模块
     * created by wangqiang
    **/
	public class AssetModule : AbstractSingletonModule<AssetModule>, InterfaceEntityLiftcycle
	{
		
		/// <summary>
		/// 根据资源名称异步加载资源
		/// </summary>
		/// <param name="assetName"></param>
		/// <param name="finishCallback"></param> 加载完成的回调
		/// <typeparam name="T"></typeparam> 成功：finishCallback传入资源对象，失败：finishCallback传入null
		public void loadAssetByAsyncAssetName<T>(string assetName, Action<T> finishCallback)
		{
			AsyncOperationHandle<T> operationHandle = Addressables.LoadAssetAsync<T>(assetName);
			operationHandle.Completed += handle =>
			{
				if (handle.IsDone)
				{
					if (handle.Status != AsyncOperationStatus.Succeeded)
					{
						PiscesLog.error("加载资源失败，资源名称：" + assetName);
						finishCallback?.Invoke(default(T));
					}
					else
					{
						finishCallback?.Invoke(handle.Result);
					}
				}
				else
				{
					PiscesLog.error("加载资源未完成，资源名称：" + assetName);
					finishCallback?.Invoke(default(T));
				}
			};
		}

		/// <summary>
		/// 根据资源label异步加载资源
		/// </summary>
		/// <param name="labelName"></param>
		/// <param name="finishCallback"></param>
		/// <typeparam name="T"></typeparam>  成功：finishCallback传入资源对象，失败：finishCallback传入null
		public void loadAssetByAsyncAssetLabel<T>(string labelName, Action<T> finishCallback)
		{
			AssetLabelReference assetLabelReference = new AssetLabelReference();
			assetLabelReference.labelString = labelName;

			AsyncOperationHandle<T> operationHandle = Addressables.LoadAssetAsync<T>(labelName);
			operationHandle.Completed += handle =>
			{
				if (handle.IsDone)
				{
					if (handle.Status != AsyncOperationStatus.Succeeded)
					{
						PiscesLog.error("加载label资源失败，资源label名称：" + labelName);
						finishCallback?.Invoke(default(T));
					}
					else
					{
						finishCallback?.Invoke(handle.Result);
					}
				}
				else
				{
					PiscesLog.error("加载label资源未完成，资源label名称：" + labelName);
					finishCallback?.Invoke(default(T));
				}
			};
		}

		/// <summary>
		/// 释放资源
		/// </summary>
		/// <param name="gameObject"></param>
		public void releaseAsset<T>(T gameObject)
		{
			Addressables.Release(gameObject);
		}

		/// <summary>
		/// 异步加载场景
		/// </summary>
		/// <param name="sceneName"></param>
		/// <param name="loadSceneMode"></param>
		/// <param name="finishCallback"></param>
		public void loadSceneAsync(string sceneName, LoadSceneMode loadSceneMode, Action<string, SceneInstance> finishCallback)
		{
			AsyncOperationHandle<SceneInstance> operationHandle = Addressables.LoadSceneAsync(sceneName, loadSceneMode);
			operationHandle.Completed += handle =>
			{
				if (handle.IsDone)
				{
					if (handle.Status != AsyncOperationStatus.Succeeded)
					{
						PiscesLog.error("加载场景失败，场景名称：" + sceneName);
						finishCallback?.Invoke(sceneName, handle.Result);
					}
					else
					{
						finishCallback?.Invoke(sceneName, handle.Result);
					}
				}
				else
				{
					PiscesLog.error("加载场景未完成，场景名称：" + sceneName);
					finishCallback?.Invoke(sceneName, handle.Result);
				}
			};
			
		}

		/// <summary>
		/// 卸载场景
		/// </summary>
		/// <param name="sceneInstance"></param>
		/// <param name="finishCallback"></param>
		public void unLoadSceneAsync(SceneInstance sceneInstance, Action<string, bool> finishCallback)
		{
			AsyncOperationHandle<SceneInstance> operationHandle = Addressables.UnloadSceneAsync(sceneInstance, UnloadSceneOptions.UnloadAllEmbeddedSceneObjects);
			operationHandle.Completed += handle =>
			{
				if (handle.IsDone)
				{
					if (handle.Status != AsyncOperationStatus.Succeeded)
					{
						PiscesLog.error("卸载场景失败，场景名称：" + sceneInstance.Scene.name);
						finishCallback?.Invoke(sceneInstance.Scene.name, false);
					}
					else
					{
						finishCallback?.Invoke(sceneInstance.Scene.name, true);
					}
				}
				else
				{
					PiscesLog.error("卸载场景未完成，场景名称：" + sceneInstance.Scene.name);
					finishCallback?.Invoke(sceneInstance.Scene.name, false);
				}
			};
		}
	}
	
}